﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace ScaffoldIt.Configuration
{
    [XmlRoot("Scaffolding")]
    public class ScaffoldItConfig
    {
        [XmlIgnore]
        public string FileName { get; set; }

        private List<Parameter> parameters = new List<Parameter>();

        public List<Parameter> Parameters
        {
            get
            {
                return this.parameters;
            }
            set
            {
                this.parameters = value;
            }
        }

        private List<Category> categories = new List<Category>();

        public List<Category> Categories
        {
            get
            {
                return this.categories;
            }
            set
            {
                this.categories = value;
            }
        }

        private List<Preset> presets = new List<Preset>();

        public List<Preset> Presets
        {
            get
            {
                return this.presets;
            }
            set
            {
                this.presets = value;
            }
        }

        public static ScaffoldItConfig Load(string filename)
        {
            XmlSerializer seriz = new XmlSerializer(typeof(ScaffoldItConfig));
            using (StreamReader reader = new StreamReader(filename))
            {
                var res = (ScaffoldItConfig)seriz.Deserialize(reader);
                res.FileName = filename;
                return res;
            }
        }

        public void Save()
        {
            if (string.IsNullOrEmpty(FileName))
            {
                throw new InvalidOperationException("File name is not available");
            }

            this.Save(FileName);
        }

        public void Save(string filename)
        {
            if (this.FileName != filename) this.FileName = filename;

            XmlSerializer seriz = new XmlSerializer(typeof(ScaffoldItConfig));
            using (StreamWriter writer = new StreamWriter(filename, false))
            {
                seriz.Serialize(writer, this);
            }
        }

        public static ScaffoldItConfig SampleConfig()
        {
            var res = new ScaffoldItConfig();

            var prmGlobal = new Parameter() { Code = "ParamName", Title = "Parameters allows to input custom value", Type = "bool", IsGlobal = false };
            res.Parameters.Add(prmGlobal);

            var cat1 = new Category() { Name = "A first category", Description = "You could nest categories to build a tree of categories and templates. When you will scaffold an entity, you will be able to choose templates individually or by categories." };
            var cat2 = new Category() { Name = "A second category"};
            res.Categories.Add(cat1);
            res.Categories.Add(cat2);
            var templ1 = new Template()
                {
                    Name = "a template",
                    ProjectName = "Put the name of one of your project here",
                    TemplateName = "scaffolding\\sample template.tt",
                    OutputName = "somefolder\\{ClassName}Scaffolded.cs",
                    Description =
                        "Templates item define the T4 template to use, the target project, and the output file name."
                };

            var prm = new Parameter() { Code = "ParamName" };
            templ1.Parameters.Add(prm);
            

             var templ2 = new Template()
                {
                    Name = "another template",
                    ProjectName = "Put the name of one of your project here",
                    TemplateName = "scaffolding\\sample template.tt",
                    OutputName = "somefolder\\{ClassName}Scaffolded.cs",
                    Description =
                        "You could use parameters and model data as parameter in template properties."
                };
            cat1.Templates.Add(templ1);
            cat1.Templates.Add(templ2);
            cat2.Templates.Add(templ1);

            var nestedcat = new Category() { Name = "A nested category" };
            nestedcat.Templates.Add(templ1);
            cat1.Categories.Add(nestedcat);

            Preset preset = new Preset() {Name = "All templates", Description="Preset allows to define sets of categories and templates"};
            var presetCat1 = new PresetCategory()
                { Category = "A first category", Templates = "a template, another template" };
            preset.Categories.Add(presetCat1);
            var nestedPresetCat = new PresetCategory() {Category = "A nested category", Templates = "a template"};
            presetCat1.Categories.Add(nestedPresetCat);

            var presetCat2 = new PresetCategory() { Category = "A second category", Templates = "a template" };
            preset.Categories.Add(presetCat2);
            res.Presets.Add(preset);

            return res;
        }
    }
}
